package com.t2two.example.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.HashMap;

/**
 * @version 1.0
 * @description: TODO
 * @author: lifei
 * @date: 2025/2/20 14:01
 */
public class SM2DecryptUtil {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static ECPrivateKeyParameters convertPrivateKey(String privateKeyHex) {
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParams = new ECDomainParameters(
                sm2ECParameters.getCurve(),
                sm2ECParameters.getG(),
                sm2ECParameters.getN(),
                sm2ECParameters.getH()
        );

        // 将私钥Hex转换为BigInteger
        java.math.BigInteger d = new java.math.BigInteger(privateKeyHex, 16);
        return new ECPrivateKeyParameters(d, domainParams);
    }

    /**
     * SM2解密
     * @param encryptedDataHex 加密后的16进制字符串
     * @param privateKey       私钥参数
     */
    public static String decrypt(String encryptedDataHex, ECPrivateKeyParameters privateKey) throws Exception {
        byte[] encryptedData = Hex.decode(encryptedDataHex);

        SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
        engine.init(false, privateKey);

        byte[] decrypted = engine.processBlock(encryptedData, 0, encryptedData.length);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        String privateKeyHex = "16cf62248840bf5d94c54502019606be14607167af43ff5d11d7b20e6407c2ff";
        String encryptedData = "042781f4e275d914c6a5a09b22377010d1d94672983b9f272103cc565c7b1986e667a9ee454f18cdc3f37a87bcb9562df79aa4db7e395a0c647762a35dceb71f8007cc67fd5a2fca1b57b8e76acc7220ad000ffd6b409e8c59315cf40dfc9b8aedf59ca9fae9881bb0217c299d5813d086d34dfc76a4f86c8c6795e6e255f5032f913d531986e3da157f684f66576102b5c66d1a69ec84a2ac69693aae543152e6be1b4b441ae79988e80e9a40eab23bd5ada671a1cff4c61a371894d40d8536d5fdb287575af4071b74db7ae1cc1aec2225c7a363b05b97cb62f9be1adce3025506cb174042a9f20c89707da138365af6cdcfce78feaddd630f2523939663be0e1d6fb03b40ed015126b497d3b9dbde7a672e6466d73250c57a34195f04f1d77afb5db2c00a3a1a152527af369e8d58e84383bc5c16bb52837fcc42b89b4f1514d27eea0252c0ad35aa40afbcf1295f051ab364786903d81bfe8faf3e6ee57a8746cc97538110711374b4fd643892a629bd7ac5a56eb9efdee04684b11633ba202002185abf4dd6fa3d10c8988132091a6ea5a2e803aacbe36ca8e7518bb1168c8873c390b6af34df653d3248342eed4ec79853344af9b3888176d7332a396ced7afd98dda3a7b73044a105c2a021630a3764ff60d324f2f34adea44e6f72fda8b0b4c9d4a1c816bee4783d043713880e9889d11ce269bdd5fe242c93463cb765f78490a590f4be4484ac05a3a3dab9dcd98e837db40c5b904591626eb4e94eabd36fc99da0496bc12b0a79d9e071aa23b202783dae7c172b0d6bee166dd30cff080225002abeecc78de75372315d473c40bfcf77d98caf00e3f82916763893fcfd208e0ea15a4a315b6b2a473d2da6a33730f457aaf2c4c10b115fc7977bfab3e8a0b20302318cd5bd044218b8976774cb9e9dd184762a1c7da903addf4dafa939466010cf7a2ab889e399a73355b38898005f78a076e5cb551f996cbb1f24406a41857d24d20a6ea498f7a8ac3265329052cf78ef7bf5eec8f53138e45673ff73ad707d4dc4ab5968ef25165885bec86c54fd54f52d20b500219e927768b7e4112b59459b387a29a4f771e1b8df0874f2432e23347546de8db5fd8b48a7982f0cbe47754037797317caddb61b8a08bc5e8b4875d5d752a13b94f3c8a2b28675f00cba557c9446e0092734af7d32838aa6197c58fce57122bc5e14f4021a57e1148cc0c68f78e43664a2de780497bb982fa40386e84e1a3d9cffed94924e61c8c3f10f5f42b557b48cf63674"; // 这里替换成实际的加密数据

        ECPrivateKeyParameters privateKey = convertPrivateKey(privateKeyHex);
        String plainText = decrypt(encryptedData, privateKey);
        System.out.println("Decrypted: " + plainText);
        ECPrivateKeyParameters privateKey1 = convertPrivateKey("3c57e96dac2d6d0dfd92e400ebb609e584b148b755968d898bd25f226aa5b636");
        String decrypt = decrypt(plainText, privateKey1);
        System.out.println("tttttttttttttttttttttt "+decrypt);
        HashMap hashMap = JSONObject.parseObject(decrypt, HashMap.class);
        Object o = hashMap.get("data");
        System.out.println("uuuuuuuuuuuuuuuuuuuuuuu "+JSONObject.toJSONString(o));
        HashMap hashMap1 = JSONObject.parseObject(o.toString(), HashMap.class);
        System.out.println("aaaaaaaaaaaaaaaaaaaaaaa "+JSONObject.toJSONString(hashMap1));
    }
}
